package org.jeecg.modules.baidu.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.modules.baidu.SearchHttpAK;
import org.jeecg.modules.baidu.constants.BDMapConstants;

import java.util.LinkedHashMap;
import java.util.Map;

public class BDMapUtil {
    /**
     * 百度地图地理编码
     * 用户可通过该功能，将结构化地址（省/市/区/街道/门牌号）解析为对应的位置坐标。地址结构越完整，地址内容越准确，解析的坐标精度越高。
     * @param address
     * @return
     * @throws Exception
     */
    public static Map<String, String> getLocationByAddress(String address) throws Exception {
        Map<String, String> geocodingParams = new LinkedHashMap<>();
        Map<String, String> resultParams = new LinkedHashMap<>();
        geocodingParams.put("address", address);
        geocodingParams.put("output", "json");

        String BDResult; //返回信息
        try {
            BDResult = SearchHttpAK.requestGetAK(BDMapConstants.BAIDUURL_GEOCODING,geocodingParams);
        } catch (Exception e) {
            e.printStackTrace();
            resultParams.put("status", "-1");
            return resultParams;
        }

        JSONObject BDJsonObject = JSON.parseObject(BDResult);
        String status = BDJsonObject.getString("status"); //状态码 0：成功 1：服务内部错误 2：参数无效 7：无返回结果
        if (!status.equals("0")) {
            resultParams.put("status", "-1");
            return resultParams;
        }

        String result = BDJsonObject.getString("result"); //返回的方案集
        JSONObject resultJsonObject = JSON.parseObject(result);
        JSONObject locationJSONArray = resultJsonObject.getJSONObject("location");

        float lng = locationJSONArray.getFloat("lng"); //经度
        float lat = locationJSONArray.getFloat("lat"); //纬度

        resultParams.put("status", "0");
        resultParams.put("lng", String.valueOf(lng));
        resultParams.put("lat", String.valueOf(lat));

        return resultParams;
    }

    /**
     * 驾车路线规划
     * 根据起终点坐标规划驾车出行路线和耗时
     * @param params
     * @return
     * @throws Exception
     */
    public static Map<String, Object> getDirectionliteDriving(Map<String, String> params) throws Exception {
        Map<String, Object> resultParams = new LinkedHashMap<>();

        String BDResult; //返回信息
        try {
            BDResult = SearchHttpAK.requestGetAK(BDMapConstants.BAIDUURL_DRIVING,params);
        } catch (Exception e) {
            e.printStackTrace();
            resultParams.put("status", "-1");
            return resultParams;
        }

        JSONObject BDJsonObject = JSON.parseObject(BDResult);
        String status = BDJsonObject.getString("status"); //状态码 0：成功 1：服务内部错误 2：参数无效 7：无返回结果
        if (!status.equals("0")) {
            return null;
        }
        String result = BDJsonObject.getString("result"); //返回的方案集
        JSONObject resultJsonObject = JSON.parseObject(result);
        JSONArray routesJSONArray = resultJsonObject.getJSONArray("routes");
        JSONObject routesJsonObject = JSON.parseObject(routesJSONArray.get(0).toString());

        resultParams.put("status", "0");
        resultParams.put("distance", routesJsonObject.getDouble("distance") / 1000); //方案距离，单位：米
        resultParams.put("duration", routesJsonObject.getDouble("duration")); //线路耗时，单位：秒
        resultParams.put("toll", routesJsonObject.getDouble("toll")); //路线的过路费预估，单位：元

        return resultParams;
    }
    
    /**
     * 驾车路线规划 V2版本
     * 根据起终点坐标规划驾车出行路线和耗时
     * @param params
     * @return
     * @throws Exception
     */
    public static Map<String, Object> getDirectionDrivingV2(Map<String, String> params) throws Exception {
        Map<String, Object> resultParams = new LinkedHashMap<>();

        String BDResult; //返回信息
        try {
            BDResult = SearchHttpAK.requestGetAK(BDMapConstants.BAIDUURL_DRIVING_V2, params);
        } catch (Exception e) {
            e.printStackTrace();
            resultParams.put("status", "-1");
            return resultParams;
        }

        JSONObject BDJsonObject = JSON.parseObject(BDResult);
        String status = BDJsonObject.getString("status"); //状态码 0：成功 1：服务内部错误 2：参数无效 7：无返回结果
        if (!status.equals("0")) {
            resultParams.put("status", status);
            resultParams.put("message", BDJsonObject.getString("message"));
            return resultParams;
        }
        
        String result = BDJsonObject.getString("result"); //返回的方案集
        JSONObject resultJsonObject = JSON.parseObject(result);
        JSONArray routesJSONArray = resultJsonObject.getJSONArray("routes");
        if (routesJSONArray != null && routesJSONArray.size() > 0) {
            JSONObject routesJsonObject = JSON.parseObject(routesJSONArray.get(0).toString());

            resultParams.put("status", "0");
            resultParams.put("distance", routesJsonObject.getDouble("distance")); //方案距离，单位：米
            resultParams.put("duration", routesJsonObject.getDouble("duration")); //线路耗时，单位：秒
            resultParams.put("toll", routesJsonObject.getDouble("toll")); //路线的过路费预估，单位：元
        } else {
            resultParams.put("status", "-1");
            resultParams.put("message", "未找到路线信息");
        }

        return resultParams;
    }

    /**
     * 逆地理编码
     * 根据经纬度坐标获取地址信息
     * @param lat 纬度
     * @param lng 经度
     * @param coordtype 坐标类型，默认为wgs84ll
     * @return
     * @throws Exception
     */
    public static Map<String, Object> getAddressByLocation(String lat, String lng, String coordtype) throws Exception {
        Map<String, Object> resultParams = new LinkedHashMap<>();
        
        Map<String, String> params = new LinkedHashMap<>();
        params.put("location", lat + "," + lng);
        params.put("output", "json");
        params.put("coordtype", coordtype != null && !coordtype.trim().isEmpty() ? coordtype : "wgs84ll");
        params.put("ret_coordtype", "bd09ll"); // 返回坐标类型

        String BDResult; //返回信息
        try {
            // 添加调试信息
            System.out.println("逆地理编码请求参数: " + params);
            System.out.println("使用AK: " + BDMapConstants.AK);
            
            BDResult = SearchHttpAK.requestGetAK(BDMapConstants.BAIDUURL_GEOCODING, params);
            System.out.println("逆地理编码响应: " + BDResult);
        } catch (Exception e) {
            e.printStackTrace();
            resultParams.put("status", "-1");
            resultParams.put("message", "请求异常：" + e.getMessage());
            return resultParams;
        }

        JSONObject BDJsonObject = JSON.parseObject(BDResult);
        String status = BDJsonObject.getString("status"); //状态码 0：成功 1：服务内部错误 2：参数无效 7：无返回结果
        if (!status.equals("0")) {
            resultParams.put("status", status);
            resultParams.put("message", BDJsonObject.getString("message"));
            return resultParams;
        }

        String result = BDJsonObject.getString("result"); //返回的结果
        if (result != null) {
            JSONObject resultJsonObject = JSON.parseObject(result);
            resultParams.put("status", "0");
            resultParams.put("formatted_address", resultJsonObject.getString("formatted_address"));
            resultParams.put("business", resultJsonObject.getString("business"));
            
            // 解析地址组件并格式化
            JSONObject addressComponent = resultJsonObject.getJSONObject("addressComponent");
            if (addressComponent != null) {
                resultParams.put("addressComponent", addressComponent);
                
                // 拼接省市区街道格式的地址
                String formattedAddress = formatAddressString(addressComponent);
                resultParams.put("formatted_address_string", formattedAddress);
            }
            
            resultParams.put("pois", resultJsonObject.getJSONArray("pois"));
        } else {
            resultParams.put("status", "-1");
            resultParams.put("message", "未找到地址信息");
        }

        return resultParams;
    }

    /**
     * 格式化地址字符串
     * 按照省市区街道的格式拼接地址
     * @param addressComponent 地址组件JSON对象
     * @return 格式化后的地址字符串
     */
    private static String formatAddressString(JSONObject addressComponent) {
        StringBuilder address = new StringBuilder();
        
        // 省份
        String province = addressComponent.getString("province");
        if (province != null && !province.trim().isEmpty()) {
            address.append(province);
        }
        
        // 城市
        String city = addressComponent.getString("city");
        if (city != null && !city.trim().isEmpty() && !city.equals(province)) {
            address.append(city);
        }
        
        // 区县
        String district = addressComponent.getString("district");
        if (district != null && !district.trim().isEmpty()) {
            address.append(district);
        }
        
        // 街道
        String street = addressComponent.getString("street");
        if (street != null && !street.trim().isEmpty()) {
            address.append(street);
        }
        
        // 街道号码
        String street_number = addressComponent.getString("street_number");
        if (street_number != null && !street_number.trim().isEmpty()) {
            address.append(street_number);
        }
        
        return address.toString();
    }

    /**
     * 逆地理编码（简化版本）
     * 根据经纬度坐标获取格式化地址
     * @param lat 纬度
     * @param lng 经度
     * @return
     * @throws Exception
     */
    public static String getFormattedAddress(String lat, String lng) throws Exception {
        Map<String, Object> result = getAddressByLocation(lat, lng, "wgs84ll");
        String status = (String) result.get("status");
        if ("0".equals(status)) {
            // 优先返回格式化地址字符串，如果没有则返回原始地址
//            String formattedAddressString = (String) result.get("formatted_address_string");
//            if (formattedAddressString != null && !formattedAddressString.trim().isEmpty()) {
//                return formattedAddressString;
//            } else {
                return (String) result.get("formatted_address");
//            }
        } else {
            return "请求失败，错误码：" + status + "，错误信息：" + result.get("message");
        }
    }

    /**
     * 测试逆地理编码方法的main方法
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("==========================================");
        System.out.println("        百度地图逆地理编码接口测试");
        System.out.println("==========================================");
        
        // 先测试一个简单的坐标
        String testLat = "22.831348";
        String testLng = "108.37486";
        
        System.out.println("测试坐标: 纬度=" + testLat + ", 经度=" + testLng);
        
        try {
            String a = getFormattedAddress(testLat, testLng);
                System.out.println("📍 简化地址: " + a);
        } catch (Exception e) {
            System.err.println("测试异常: " + e.getMessage());
            e.printStackTrace();
        }


    }
}